// 手写源码20210831


// 自定义bind函数
// Function.prototype.myBind = function(obj){
//     obj.func = this

//     return function (){
//         obj.func(...arguments)
//     }
// }

// const obj = {
//     str: 2
// }

// function func1 (a) {
//     console.log(this.str + a)
// }

// const func2 = func1.myBind(obj)

// func2(1)






// // 实现一个数据转换为千分位
// const num = 1023424394562374

// function transfer(num) {
//     let str = ""

//     const num1 = num/1000

//     if(num1<1){
//         return num.toString()
//     } else {
//         // Math.floor 和 parseInt 有什么区别？
//         const num2 = parseInt(num1)
//         const string1 = transfer(num2)
//         const string2 = num1.toString().split(".")[1]
//         return string1 + "," + string2
//     }
// }

// function transfer2(num) {
//     let str = num.toString()
//     let string = ""

//     let i = 0
//     while(i<str.length){
//         const j = str.length - 1 - i
//         string += str[j]

//         if(i!==str.length-1&&(str.length-1-j)%3 === 0) 
//         string += ","
//         i++
//     }

//     return string
// }

// function transfer3(num) {
//     const numArray = num.toString().split("").reverse()
//     let i = 0
//     let arr = []

//     while(i<numArray.length){
//         arr.push(numArray[i])
//         if((i+1)%3 === 0){
//             arr.push(",")
//         }
//         i++
//     }


//     return arr.reverse().join("")
// }

// console.log(transfer3(num))





// 数组去重
// 1、indexOf(NaN) 永远等于 -1，找不出相同的应该使用includes方法
// 2、如果用hash，{} 这种方式, 属性是 {} 的时候会有问题，属性名会被改成[object Object]，不能判断是否同一个属性。
// 3、如果用hash, Map这种方式没问题，参考以下测试用例
Array.prototype.uniq = function () {
    let array = this
    // let s = []

    // return array.filter(item => {
    //     if (!s.includes(item)) {
    //         s.push(item)
    //         return true
    //     }
    //     return false
    // })

    let s = new Map()

    let p = array.filter(item => {
        if (!s.get(item)) {
            s.set(item, true)
            return true
        }
        return false
    })

    console.log(s)
    return p
}


// const arr = [true, false, null, undefined, NaN, 0, 1, {}, {}, 'a', 'a', NaN].uniq()
function test() {
    var a = [true, false, null, undefined, NaN, 0, 1, { a: 1 }, {}, 'a', 'a', NaN].uniq();
    console.log(a)

    return a.length === 10 &&
        a[1] === false &&
        a[0] === true &&
        a[3] === undefined &&
        a[2] === null &&
        isNaN(a[4]);
}


console.log(test())



function count(str) {
    let obj = {}
    str.split("").forEach(w => {
        if (w !== " ")
            obj[w] = obj[w] ? ++obj[w] : 1
    })

    return obj
}
console.log(count('hello world'))


function createModule(str1, str2) {

    let obj = {
        greeting: str1,
        name: str2
    }

    obj.sayIt = function () {
        return this.greeting + "," + this.name
    }

    return obj
}

var o = createModule('hello', 'matt');

function aa() { var o = createModule('hello', 'matt'); return o.sayIt(); }
console.log(aa())




/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @param {number} k
 * @return {number[][]}
 */
var kSmallestPairs = function (nums1, nums2, k) {

    let i = 0
    let j = 0
    let arr = []

    while (i < nums1.length) {
        j = 0
        while (j < nums2.length) {
            arr.push([nums1[i], nums2[j]])
            j++
        }
        i++
    }

    console.log(arr)

    const sum = (arr) => {
        return arr[0] + arr[1]
    }

    var x = arr.sort((a, b) => { return sum(a) - sum(b) }).slice(0, k)

    return x
};

// console.log(kSmallestPairs([1,7,11], [2,4,6], 6))

// console.log(kSmallestPairs([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],1000))




function myCurry() {

    return function () {

    }

}

// function func(a,b,c){

// }


// let a = myCurry(func)

// a(1,2,3)

// a(1,2)(3)

// a(1)(2)(3)

// 快速选择算法找到第k大的数
var findKthLargest = function (nums, k) {
    const swap = (arr, a, b) => {
        const temp = arr[b]
        arr[b] = arr[a]
        arr[a] = temp
    }

    const quickSelectFlag = (arr, k) => {
        if (arr.length < 2) {
            return arr
        }

        let flag = 0
        let i = 0
        let j = arr.length - 1
        while (i < j) {
            while (i < j && arr[flag] >= arr[j]) j--
            swap(arr, flag, j)
            flag = j

            while (i < j && arr[flag] <= arr[i]) i++
            swap(arr, flag, i)
            flag = i
        }

        return flag
    }

    const quickSelect = (arr, k) => {
        const flag = quickSelectFlag(arr, k)

        if (k === flag) {
            return arr[flag]
        }
        else if (k < flag) {
            return quickSelect(arr.slice(0, flag), k)
        }
        else {
            return quickSelect(arr.slice(flag + 1, arr.length), k - flag - 1)
        }
    }

    return quickSelect(nums, k - 1)
};


console.log(findKthLargest([3, 2, 3, 1, 2, 4, 5, 5, 6], 2))


// 父类
function Parent (){}
Parent.prototype.a = 1

// 子类继承
// Child.prototype.__proto__ === Parent.prototype
function Child(){}
Child.prototype = ObjectCreate(Parent.prototype)

// 子类实例
// p.__proto__ === Child.prototype
var p = new Child()
p.__proto__.a = 2

console.log(p.__proto__.a) // 2
console.log(Parent.prototype.a)// 1




// 自定义 Object.create()
function ObjectCreate (prototype) {
    function Construct () {
    }

    Construct.prototype = prototype

    return new Construct()
}




// 转换数组到树形结构
const arr = [
    {id: 4, name: "部门3", pid: 3},
    {id: 1, name: "总部", pid: 0},
    {id: 2, name: "部门1", pid: 1},
    {id: 3, name: "部门1", pid: 1},
    {id: 5, name: "部门2", pid: 2},
    {id: 6, name: "部门2", pid: 2}
]


// 有序数组
function transferArr(arr) {
    let obj = {}

    arr.map(item => {
        obj[item.id] = item
    })

    arr.map(item => {
        let parent = obj[item.pid]
        if(parent){
            if(parent.children){
                parent.children.push(item)
            } else {
                parent.children = [item]
            }
        }
    })

    return obj[1]
}

// 无序数组
function tansUnsortArr(arr) {
    let obj = {}
    let head = []

    arr.map(item => {
        obj[item.id] = item
    })

    // 关键在于for-in可以查看obj中是否还存在元素、push过后item就换了位置
    for(let id in obj){
        let item = obj[id]
        if(item.pid === 0){
            head.push(item)
        } else {
            let parent = obj[item.pid]
            if(parent){
                parent.childern = parent.childern || []
                parent.childern.push(item)
            }
        }
    }

    return head[0]
}

console.log(tansUnsortArr(arr))



















// #000
// #000000
// #ffffff

// 转换颜色
function hex2rgb(hex) {
    if(!hex){
        return hex
    }

    if(hex.length !== 4 && hex.length !== 7){
        // throw(new Error("请输入正确的长度！"))
        return hex
    }
    
    if(!/^#[a-fA-F0-9]*$/.test(hex)){
        return hex
    }

    const m = {
        a: 10,
        b: 11,
        c: 12,
        d: 13,
        e: 14,
        f: 15
    }
    
    const isWord = (w) => {
        return /[a-zA-Z]/gi.test(w)
    }
    
    const getNum = (w) => {
        if(isWord(w)){
            w = w.toLowerCase()
            return m[w]
        }

        return Number(w)
    }
    
    const transferCode = (code) => {
        if(code.length < 2){
            return getNum(code) * 16 + getNum(code)
        } 
        let arr = code.split("")
        return getNum(arr[0]) * 16 + getNum(arr[1])
    }

    const str = hex.replace("#", "")
    let rgb = []
    if(str.length === 3) {
        rgb = [
            transferCode(str[0]),
            transferCode(str[1]),
            transferCode(str[2])
        ]
    }

    if(str.length === 6) {
        rgb = [
            transferCode(str.slice(0,2)),
            transferCode(str.slice(2,4)),
            transferCode(str.slice(4,6))
        ]
    }
    console.log("rgb:", rgb)
    return `rgb(${rgb[0]},${rgb[1]},${rgb[2]})`

}



console.log(hex2rgb("#001"))
















